﻿using IdentityModel.Client;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Xml.Linq;
using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services;

namespace Himp.Platform
{
    public class ActiviWorkflowManager : DomainService, IWorkflowManager
    {
        private readonly IHttpClientFactory _httpClientFactory;
        private string _baseUrl = "http://112.33.34.123:8084/workflow";

        /// <summary>
        /// 
        /// </summary>
        /// <param name="httpClientFactory"></param>
        public ActiviWorkflowManager(IHttpClientFactory httpClientFactory) 
        {
            _httpClientFactory = httpClientFactory;
        }

        /// <summary>
        /// 获取工作流模型
        /// </summary>
        /// <returns></returns>
        public async Task<List<WorkflowModel>> GetWorkflowModel(int? status)
        {
            List<WorkflowModel> processModels = new List<WorkflowModel>();
            var client = _httpClientFactory.CreateClient();
            var url = string.Empty;

            switch (status)
            {
                case 1: url = $"{_baseUrl}/flow/isdeloy"; break; //部署
                case 2: url = $"{_baseUrl}/flow/notdeloy"; break; //未部署
                default: url = $"{_baseUrl}/flow/actremodel"; break; //全部
            }

            var responseModel = await client.GetAsync(url);

            if (responseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var activiProcessModels = await responseModel.Content.ReadFromJsonAsync<List<ActiviProcessModel>>();

                foreach (var item in activiProcessModels)
                {
                    WorkflowModel processModel = new WorkflowModel(item.id_, item.name_, item.version_, item.create_TIME_);
                    processModel.LastUpdateTime = item.last_UPDATE_TIME_;
                    processModel.WorkflowModelStas = item.suspension_STATE_.HasValue ? (EnumWorkflowModelStas)item.suspension_STATE_ : EnumWorkflowModelStas.未部署;
                    processModel.DeploymentId = item.deployment_ID_;
                    processModel.DeployKey = item.deploy_KEY_;
                    processModel.EditorSourceExtraValueId = item.editor_SOURCE_EXTRA_VALUE_ID_;
                    processModel.EditorSourceValueId = item.editor_SOURCE_VALUE_ID_;
                    processModels.Add(processModel);
                }
            }

            return processModels;
        }

        /// <summary>
        /// 删除工作流模型
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<string> DeleteWorkflowModel(string id)
        {
            var client = _httpClientFactory.CreateClient();
            var url = $"{_baseUrl}/flow/deleteModel";
            var req = new { modelId = id };

            var responseModel = await client.PostAsJsonAsync(url, req);

            if (responseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var resultString = await responseModel.Content.ReadAsStringAsync();

                return resultString;
            }
            else
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 部署工作流模型
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<string> DeployWorkflowModel(string id, string workflowName)
        {
            var client = _httpClientFactory.CreateClient();
            var url = $"{_baseUrl}/flow/deploy";
            var req = new 
            { 
                modelId = id,
                processName = workflowName
            };

            var responseModel = await client.PostAsJsonAsync(url, req);

            if (responseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var resultString = await responseModel.Content.ReadAsStringAsync();

                return resultString;
            }
            else
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 激活/挂起工作流
        /// </summary>
        /// <returns></returns>
        public async Task<string> ActivateWorkflowModel(string deploymentKey)
        {
            var client = _httpClientFactory.CreateClient();
            var url = $"{_baseUrl}/flow/activateOrPend";

            var req = new
            {
                deploymentKey
            };

            var responseModel = await client.PostAsJsonAsync(url, req);

            if (responseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var resultString = await responseModel.Content.ReadAsStringAsync();

                return resultString;
            }
            else
            {
                return string.Empty;
            }
        }

        public async Task<List<WorkflowInstance>> GetProcessInstance(string startTime, string endTime, EnumWorkflowInstanceStas status)
        {
            List<WorkflowInstance> processInstances = new List<WorkflowInstance>();
            var client = _httpClientFactory.CreateClient();
            var url = string.Empty;

            switch (status)
            {
                case EnumWorkflowInstanceStas.激活: url = $"{_baseUrl}/monitor/queryactive"; break; //激活
                case EnumWorkflowInstanceStas.挂起: url = $"{_baseUrl}/monitor/querypend"; break; //挂起
                case EnumWorkflowInstanceStas.完成: url = $"{_baseUrl}/monitor/completed"; break; //完成
                default: url = $"{_baseUrl}/monitor/queryactive"; break; //激活
            }

            var reqPars = new
            {
                startTime,
                endTime,
            };

            var request = new HttpRequestMessage(HttpMethod.Get, url);
            request.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(reqPars), null, "application/json");
            var responseModel = await client.SendAsync(request);

            if (responseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var activiProcessModels = await responseModel.Content.ReadFromJsonAsync<List<ActivitiProcessInstance>>();

                foreach (var item in activiProcessModels)
                {
                    //获取流程模型对应的类别
                    WorkflowInstance workflowInstance = new WorkflowInstance();
                    workflowInstance.Id = item.id;
                    workflowInstance.WorkflowInstanceCodg = item.ProcessInstanceId;
                    workflowInstance.Begintime = item.processStartTime;
                    workflowInstance.Fintime = item.processEndTime;
                    workflowInstance.WorkflowModelId = item.modelId;
                    workflowInstance.WorkflowInstanceName = item.modelName;
                    workflowInstance.Parameters = item.variableMap;
                    StringBuilder workflowInstanceContdescSb = new StringBuilder();
                    workflowInstance.WorkflowInstanceContdesc = workflowInstanceContdescSb.ToString();
                    workflowInstance.CurrNodeCodg = item.taskId;
                    workflowInstance.CurrNodeName = item.taskName;
                    workflowInstance.WorkflowInstanceStas = (EnumWorkflowInstanceStas)item.suspensionCode;

                    processInstances.Add(workflowInstance);
                }
            }

            return processInstances;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="processDefinitionId"></param>
        /// <param name="assocUsers"></param>
        /// <param name="startId"></param>
        /// <param name="bizPars"></param>
        /// <returns></returns>
        public async Task<string> StartWorkflowInstance(string processDefinitionId, Dictionary<string, List<string>> assocUsers, string startId, Dictionary<string, object> bizPars)
        {
            var client = _httpClientFactory.CreateClient();
            var url = $"{_baseUrl}/application/start";

            Dictionary<string, object> reqPars = new Dictionary<string, object>();
            reqPars.Add("startId", startId);
            reqPars.Add("processDefinitionId", processDefinitionId);
            reqPars.Add("groupCode", assocUsers);
            reqPars.Add("businessVariables", bizPars);

            var responseModel = await client.PostAsJsonAsync(url, reqPars);

            if (responseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var resultString = await responseModel.Content.ReadAsStringAsync();

                return resultString;
            }
            else
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="processInstanceId"></param>
        /// <param name="userId"></param>
        /// <param name="bizPars"></param>
        /// <returns></returns>
        public async Task<string> ExecWorkflowInstance(string processInstanceId,  string userId, Dictionary<string, object> bizPars)
        {
            var client = _httpClientFactory.CreateClient();
            var url = $"{_baseUrl}/monitor/claimTask";

            Dictionary<string, object> reqPars = new Dictionary<string, object>();
            reqPars.Add("processinstanceid", processInstanceId);
            reqPars.Add("workId", userId);
            reqPars.Add("businessVariables", bizPars);

            var responseModel = await client.PostAsJsonAsync(url, reqPars);

            if (responseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var resultString = await responseModel.Content.ReadAsStringAsync();

                return resultString;
            }
            else
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 完成流程
        /// </summary>
        /// <param name="deployKey"></param>
        /// <param name="pars"></param>
        /// <returns></returns>
        public async Task<string> FinishWorkflowInstance(string workflowInstanceId, string userId)
        {
            var client = _httpClientFactory.CreateClient();
            var url = $"{_baseUrl}/monitor/claimTask";
            var req = new
            {
                processinstanceid = workflowInstanceId,
                workId = userId
            };

            var responseModel = await client.PostAsJsonAsync(url, req);

            if (responseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var resultString = await responseModel.Content.ReadAsStringAsync();

                return resultString;
            }
            else
            {
                return string.Empty;
            }
        }
    }
}
